Skip to content

Surface.influence_function: respect finite edges (no bleed past the end)#241

Open
lmoresi wants to merge 1 commit into
developmentfrom
bugfix/fault-influence-edge
Open

Surface.influence_function: respect finite edges (no bleed past the end)#241
lmoresi wants to merge 1 commit into
developmentfrom
bugfix/fault-influence-edge

Conversation

@lmoresi

@lmoresi lmoresi commented Jun 16, 2026

Copy link
Copy Markdown
Member

Problem

Surface.influence_function built its influence on Abs(self.distance.sym[0]) — the Abs of the signed distance field. The signed distance changes sign across the surface and its zero-contour follows the surface's infinite line/plane, so it extends past a finite edge. Any non-nodal evaluation interpolates the signed field through ~0 along that extension, and Abs() of that leaves a spurious high-influence streak well beyond the end of the surface.

Concretely: a dipping weak-fault zone (finite segment) lit up a weak band along the fault's line-extension, far beyond the fault tip — contaminating the viscosity field where the fault does not exist.

The per-node distances are already edge-clamped (the segment/surface distance falls back to the nearest endpoint), so the magnitude is correct at the nodes — the artifact is purely the interpolation of the sign-flipping field, which Abs cannot undo (abs of an interpolated zero-crossing is still ~0).

Fix

Store a companion unsigned, edge-clamped distance field Surface.abs_distance (populated as |signed distances| in _compute_distance_field) and build influence_function on it. The unsigned field is >= 0 everywhere and, beyond an edge, is simply the radial distance to the endpoint, so its interpolant never crosses zero there — the influence decays correctly past a finite edge.

Signed distance is unchanged and still available for sided (d > 0) properties.

Test

tests/test_0851_surface_influence_edge.py embeds a finite segment and checks the influence decays beyond the tip. Along the line extension (>= 3·width past the tip) the old basis spikes to influence ~1.0 on the mesh edges crossing the extension; the fix keeps it ~0. A second test confirms abs_distance tracks the geometric edge-clamped distance between nodes.

Existing surface tests (test_0850_surfaces.py, test_0762_fault_metric_tensor.py) pass unchanged (82 passed, 1 pre-existing xfail).

Underworld development team with AI support from Claude Code

Surface.influence_function built its influence on `Abs(self.distance.sym[0])`,
the Abs of the *signed* distance MeshVariable. The signed distance changes sign
across the surface and its zero-contour follows the surface's infinite
line/plane, so it extends PAST a finite edge. Any non-nodal evaluation
interpolates the signed field through ~0 along that extension, and Abs() of that
leaves a spurious high-influence streak well beyond the end of the surface
(e.g. a weak fault zone bleeding past the fault tip). The per-node distances are
already edge-clamped (the segment/surface distance falls back to the nearest
endpoint), so the magnitude is correct at the nodes — the artifact is purely the
interpolation of the sign-flipping field.

Fix: store a companion UNSIGNED, edge-clamped distance field
(`Surface.abs_distance`, populated as |signed distances| in
_compute_distance_field) and build influence_function on it. The unsigned field
is >= 0 everywhere and, beyond an edge, is just the radial distance to the
endpoint, so its interpolant never crosses zero there.

Adds tests/test_0851_surface_influence_edge.py: an embedded finite segment whose
influence must decay beyond the tip — along the line extension the old basis
spikes to ~1.0, the fix keeps it ~0; also checks abs_distance tracks the
geometric edge-clamped distance between nodes.

Underworld development team with AI support from Claude Code
Copilot AI review requested due to automatic review settings June 16, 2026 01:40

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes an interpolation artifact in Surface.influence_function where using Abs() on the signed distance field could create a spurious high-influence streak extending beyond finite surface edges (e.g., past a segment tip). The fix introduces a companion unsigned, edge-clamped distance field and uses it for influence evaluation so influence decays correctly beyond finite endpoints.

Changes:

  • Add Surface.abs_distance: an unsigned, edge-clamped distance MeshVariable computed alongside the signed distance.
  • Update Surface.influence_function to use abs_distance rather than Abs(surface.distance.sym[0]).
  • Add a regression test that probes non-nodal points along a segment’s line extension to ensure influence does not “bleed” past the finite tip, plus a geometry-consistency check for abs_distance.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

File Description
src/underworld3/meshing/surfaces.py Adds and populates abs_distance and switches influence_function to use it for edge-respecting influence decay.
tests/test_0851_surface_influence_edge.py New regression tests verifying influence decays beyond a finite edge and abs_distance matches geometric edge-clamped distances.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants